home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / LoadSaveNoteVectors.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  13.7 KB  |  445 lines  |  [TEXT/KAHL]

  1. /* LoadSaveNoteVectors.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "LoadSaveNoteVectors.h"
  31. #include "Array.h"
  32. #include "FrameObject.h"
  33. #include "NoteObject.h"
  34. #include "Memory.h"
  35. #include "BufferedFileInput.h"
  36. #include "BufferedFileOutput.h"
  37.  
  38.  
  39. /* Note Vector Subblock Format: */
  40. /*   1-byte format version number */
  41. /*       should be 1 */
  42. /*   4-byte little endian number of frames in the vector */
  43. /*   * for each frame: */
  44. /*       4-byte little endian number of notes in the frame */
  45. /*       n-bytes of data for all of the notes (see note object format) */
  46. /*   4-byte little endian number of records in the tie matrix */
  47. /*   * for each tie matrix entry: */
  48. /*       4-byte little endian index of the source frame */
  49. /*       4-byte little endian index of the source note in the frame */
  50. /*       4-byte little endian index of the target frame */
  51. /*       4-byte little endian index of the target note in the frame */
  52.  
  53.  
  54. /* this reads in notes from the file and the tie matrix and builts a note */
  55. /* vector from the information. */
  56. FileLoadingErrors        ReadNoteVector(struct ArrayRec** FrameArrayOut,
  57.                                             struct BufferedInputRec* Input)
  58.     {
  59.         signed long                NumberOfFrames;
  60.         long                            FrameScan;
  61.         ArrayRec*                    FrameArray;
  62.         FileLoadingErrors    Error;
  63.         signed long                NumberOfTieRecords;
  64.         long                            TieScan;
  65.         unsigned char            UnsignedChar;
  66.  
  67.         CheckPtrExistence(Input);
  68.  
  69.         /*   1-byte format version number */
  70.         /*       should be 1 */
  71.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  72.             {
  73.                 Error = eFileLoadDiskError;
  74.              FailurePointneg1:
  75.                 return Error;
  76.             }
  77.         if (UnsignedChar != 1)
  78.             {
  79.                 Error = eFileLoadBadFormat;
  80.              FailurePoint0:
  81.                 goto FailurePointneg1;
  82.             }
  83.  
  84.         FrameArray = NewArray();
  85.         if (FrameArray == NIL)
  86.             {
  87.                 Error = eFileLoadOutOfMemory;
  88.              FailurePoint1:
  89.                 goto FailurePoint0;
  90.             }
  91.  
  92.         /*   4-byte little endian number of frames in the vector */
  93.         if (!ReadBufferedSignedLongLittleEndian(Input,&NumberOfFrames))
  94.             {
  95.                 long                            FrameLimit;
  96.  
  97.                 Error = eFileLoadDiskError;
  98.              FailurePoint2:
  99.                 FrameScan = ArrayGetLength(FrameArray);
  100.                 for (FrameScan = 0; FrameScan < FrameLimit; FrameScan += 1)
  101.                     {
  102.                         DisposeFrameAndContents((FrameObjectRec*)ArrayGetElement(
  103.                             FrameArray,FrameScan));
  104.                     }
  105.                 DisposeArray(FrameArray);
  106.                 goto FailurePoint1;
  107.             }
  108.         if (NumberOfFrames < 0)
  109.             {
  110.                 Error = eFileLoadBadFormat;
  111.              FailurePoint3:
  112.                 goto FailurePoint2;
  113.             }
  114.  
  115.         /*   * for each frame: */
  116.         /*       4-byte little endian number of notes in the frame */
  117.         /*       n-bytes of data for all of the notes */
  118.         for (FrameScan = 0; FrameScan < NumberOfFrames; FrameScan += 1)
  119.             {
  120.                 signed long                    NumberOfNotes;
  121.                 long                                NoteScan;
  122.                 FrameObjectRec*            FrameObject;
  123.  
  124.                 if (!ReadBufferedSignedLongLittleEndian(Input,&NumberOfNotes))
  125.                     {
  126.                         Error = eFileLoadDiskError;
  127.                      FailurePoint4:
  128.                         goto FailurePoint3;
  129.                     }
  130.  
  131.                 FrameObject = NewFrame();
  132.                 if (FrameObject == NIL)
  133.                     {
  134.                         Error = eFileLoadOutOfMemory;
  135.                      FailurePoint4a:
  136.                         goto FailurePoint4;
  137.                     }
  138.  
  139.                 for (NoteScan = 0; NoteScan < NumberOfNotes; NoteScan += 1)
  140.                     {
  141.                         NoteObjectRec*            Note;
  142.  
  143.                         Error = NoteObjectNewFromFile(&Note,Input);
  144.                         if (Error != eFileLoadNoError)
  145.                             {
  146.                              FailurePoint4b:
  147.                                 DisposeFrameAndContents(FrameObject);
  148.                                 goto FailurePoint4a;
  149.                             }
  150.  
  151.                         if (((NumNotesInFrame(FrameObject) > 1) && IsItACommand(Note))
  152.                             || IsThisACommandFrame(FrameObject))
  153.                             {
  154.                                 Error = eFileLoadBadFormat;
  155.                              FailurePoint4ba:
  156.                                 DisposeNote(Note);
  157.                                 goto FailurePoint4b;
  158.                             }
  159.  
  160.                         if (!AppendNoteToFrame(FrameObject,Note))
  161.                             {
  162.                                 Error = eFileLoadOutOfMemory;
  163.                              FailurePoint4bb:
  164.                                 goto FailurePoint4ba;
  165.                             }
  166.                     }
  167.  
  168.                 if (!ArrayAppendElement(FrameArray,FrameObject))
  169.                     {
  170.                         Error = eFileLoadOutOfMemory;
  171.                         goto FailurePoint4b;
  172.                     }
  173.             }
  174.  
  175.         /*   4-byte little endian number of records in the tie matrix */
  176.         if (!ReadBufferedSignedLongLittleEndian(Input,&NumberOfTieRecords))
  177.             {
  178.                 Error = eFileLoadDiskError;
  179.              FailurePoint5:
  180.                 goto FailurePoint4;
  181.             }
  182.         if (NumberOfTieRecords < 0)
  183.             {
  184.                 Error = eFileLoadBadFormat;
  185.              FailurePoint6:
  186.                 goto FailurePoint5;
  187.             }
  188.  
  189.         /*   * for each tie matrix entry: */
  190.         /*       4-byte little endian index of the source frame */
  191.         /*       4-byte little endian index of the source note in the frame */
  192.         /*       4-byte little endian index of the target frame */
  193.         /*       4-byte little endian index of the target note in the frame */
  194.         for (TieScan = 0; TieScan < NumberOfTieRecords; TieScan += 1)
  195.             {
  196.                 signed long                    SourceFrameIndex;
  197.                 signed long                    SourceNoteIndex;
  198.                 signed long                    TargetFrameIndex;
  199.                 signed long                    TargetNoteIndex;
  200.                 FrameObjectRec*            SourceFrame;
  201.                 FrameObjectRec*            TargetFrame;
  202.                 NoteObjectRec*            SourceNote;
  203.                 NoteObjectRec*            TargetNote;
  204.  
  205.                 if (!ReadBufferedSignedLongLittleEndian(Input,&SourceFrameIndex))
  206.                     {
  207.                         Error = eFileLoadDiskError;
  208.                      FailurePoint7:
  209.                         goto FailurePoint6;
  210.                     }
  211.                 if (SourceFrameIndex < 0)
  212.                     {
  213.                         Error = eFileLoadBadFormat;
  214.                      FailurePoint7a:
  215.                         goto FailurePoint7;
  216.                     }
  217.                 if (!ReadBufferedSignedLongLittleEndian(Input,&SourceNoteIndex))
  218.                     {
  219.                         Error = eFileLoadDiskError;
  220.                      FailurePoint7b:
  221.                         goto FailurePoint7a;
  222.                     }
  223.                 if (SourceNoteIndex < 0)
  224.                     {
  225.                         Error = eFileLoadBadFormat;
  226.                      FailurePoint7c:
  227.                         goto FailurePoint7b;
  228.                     }
  229.                 if (!ReadBufferedSignedLongLittleEndian(Input,&TargetFrameIndex))
  230.                     {
  231.                         Error = eFileLoadDiskError;
  232.                      FailurePoint7d:
  233.                         goto FailurePoint7c;
  234.                     }
  235.                 if (TargetFrameIndex < 0)
  236.                     {
  237.                         Error = eFileLoadBadFormat;
  238.                      FailurePoint7e:
  239.                         goto FailurePoint7d;
  240.                     }
  241.                 if (!ReadBufferedSignedLongLittleEndian(Input,&TargetNoteIndex))
  242.                     {
  243.                         Error = eFileLoadDiskError;
  244.                      FailurePoint7f:
  245.                         goto FailurePoint7e;
  246.                     }
  247.                 if (TargetNoteIndex < 0)
  248.                     {
  249.                         Error = eFileLoadBadFormat;
  250.                      FailurePoint7g:
  251.                         goto FailurePoint7f;
  252.                     }
  253.                 if ((TargetFrameIndex <= SourceFrameIndex)
  254.                     || (TargetFrameIndex >= ArrayGetLength(FrameArray))
  255.                     || (SourceFrameIndex >= ArrayGetLength(FrameArray)))
  256.                     {
  257.                         Error = eFileLoadBadFormat;
  258.                      FailurePoint7h:
  259.                         goto FailurePoint7g;
  260.                     }
  261.                 SourceFrame = (FrameObjectRec*)ArrayGetElement(FrameArray,SourceFrameIndex);
  262.                 CheckPtrExistence(SourceFrame);
  263.                 TargetFrame = (FrameObjectRec*)ArrayGetElement(FrameArray,TargetFrameIndex);
  264.                 CheckPtrExistence(TargetFrame);
  265.                 if ((SourceNoteIndex >= NumNotesInFrame(SourceFrame))
  266.                     || (TargetNoteIndex >= NumNotesInFrame(TargetFrame)))
  267.                     {
  268.                         Error = eFileLoadBadFormat;
  269.                      FailurePoint7i:
  270.                         goto FailurePoint7h;
  271.                     }
  272.                 SourceNote = GetNoteFromFrame(SourceFrame,SourceNoteIndex);
  273.                 CheckPtrExistence(SourceNote);
  274.                 TargetNote = GetNoteFromFrame(TargetFrame,TargetNoteIndex);
  275.                 CheckPtrExistence(TargetNote);
  276.                 if (IsItACommand(SourceNote) || IsItACommand(TargetNote))
  277.                     {
  278.                         Error = eFileLoadBadFormat;
  279.                      FailurePoint7j:
  280.                         goto FailurePoint7i;
  281.                     }
  282.                 PutNoteTieTarget(SourceNote,TargetNote);
  283.             }
  284.  
  285.         *FrameArrayOut = FrameArray;
  286.         return eFileLoadNoError;
  287.     }
  288.  
  289.  
  290. /* this writes out the information for each note and then writes the tie matrix */
  291. /* to the file. */
  292. FileLoadingErrors        WriteNoteVector(struct ArrayRec* ArrayOfFrames,
  293.                                             struct BufferedOutputRec* Output)
  294.     {
  295.         long                            NumberOfFrames;
  296.         long                            FrameScan;
  297.         long                            NumberOfTieRecords;
  298.  
  299.         CheckPtrExistence(ArrayOfFrames);
  300.         CheckPtrExistence(Output);
  301.  
  302.         /*   1-byte format version number */
  303.         /*       should be 1 */
  304.         if (!WriteBufferedUnsignedChar(Output,1))
  305.             {
  306.                 return eFileLoadDiskError;
  307.             }
  308.  
  309.         /*   4-byte little endian number of frames in the vector */
  310.         NumberOfFrames = ArrayGetLength(ArrayOfFrames);
  311.         if (!WriteBufferedSignedLongLittleEndian(Output,NumberOfFrames))
  312.             {
  313.                 return eFileLoadDiskError;
  314.             }
  315.  
  316.         /*   * for each frame: */
  317.         /*       4-byte little endian number of notes in the frame */
  318.         /*       n-bytes of data for all of the notes */
  319.         NumberOfTieRecords = 0;
  320.         for (FrameScan = 0; FrameScan < NumberOfFrames; FrameScan += 1)
  321.             {
  322.                 FrameObjectRec*        Frame;
  323.                 long                            NumberOfNotes;
  324.                 long                            NoteScan;
  325.                 FileLoadingErrors    Error;
  326.  
  327.                 Frame = (FrameObjectRec*)ArrayGetElement(ArrayOfFrames,FrameScan);
  328.                 CheckPtrExistence(Frame);
  329.                 NumberOfNotes = NumNotesInFrame(Frame);
  330.                 if (!WriteBufferedSignedLongLittleEndian(Output,NumberOfNotes))
  331.                     {
  332.                         return eFileLoadDiskError;
  333.                     }
  334.                 for (NoteScan = 0; NoteScan < NumberOfNotes; NoteScan += 1)
  335.                     {
  336.                         NoteObjectRec*        Note;
  337.  
  338.                         Note = GetNoteFromFrame(Frame,NoteScan);
  339.                         if (!IsItACommand(Note) && (GetNoteTieTarget(Note) != NIL))
  340.                             {
  341.                                 NumberOfTieRecords += 1;
  342.                             }
  343.                         Error = NoteObjectWriteDataOut(Note,Output);
  344.                         if (Error != eFileLoadNoError)
  345.                             {
  346.                                 return Error;
  347.                             }
  348.                     }
  349.             }
  350.  
  351.         /*   4-byte little endian number of records in the tie matrix */
  352.         if (!WriteBufferedSignedLongLittleEndian(Output,NumberOfTieRecords))
  353.             {
  354.                 return eFileLoadDiskError;
  355.             }
  356.  
  357.         /*   * for each tie matrix entry: */
  358.         /*       4-byte little endian index of the source frame */
  359.         /*       4-byte little endian index of the source note in the frame */
  360.         /*       4-byte little endian index of the target frame */
  361.         /*       4-byte little endian index of the target note in the frame */
  362.         for (FrameScan = 0; FrameScan < NumberOfFrames; FrameScan += 1)
  363.             {
  364.                 FrameObjectRec*        Frame;
  365.                 long                            NumberOfNotes;
  366.                 long                            NoteScan;
  367.  
  368.                 Frame = (FrameObjectRec*)ArrayGetElement(ArrayOfFrames,FrameScan);
  369.                 CheckPtrExistence(Frame);
  370.                 NumberOfNotes = NumNotesInFrame(Frame);
  371.                 for (NoteScan = 0; NoteScan < NumberOfNotes; NoteScan += 1)
  372.                     {
  373.                         NoteObjectRec*        Note;
  374.  
  375.                         Note = GetNoteFromFrame(Frame,NoteScan);
  376.                         if (!IsItACommand(Note))
  377.                             {
  378.                                 NoteObjectRec*        TieTarget;
  379.  
  380.                                 TieTarget = GetNoteTieTarget(Note);
  381.                                 if (TieTarget != NIL)
  382.                                     {
  383.                                         long                            SubFrameScan;
  384.  
  385.                                         NumberOfTieRecords -= 1;
  386.                                         for (SubFrameScan = FrameScan + 1; SubFrameScan < NumberOfFrames;
  387.                                             SubFrameScan += 1)
  388.                                             {
  389.                                                 FrameObjectRec*        SearchFrame;
  390.                                                 long                            SubNumNotes;
  391.                                                 long                            SubNoteScan;
  392.  
  393.                                                 SearchFrame = (FrameObjectRec*)ArrayGetElement(ArrayOfFrames,
  394.                                                     SubFrameScan);
  395.                                                 CheckPtrExistence(SearchFrame);
  396.                                                 SubNumNotes = NumNotesInFrame(SearchFrame);
  397.                                                 for (SubNoteScan = 0; SubNoteScan < SubNumNotes; SubNoteScan += 1)
  398.                                                     {
  399.                                                         NoteObjectRec*        SearchNote;
  400.  
  401.                                                         SearchNote = GetNoteFromFrame(SearchFrame,SubNoteScan);
  402.                                                         if (!IsItACommand(SearchNote))
  403.                                                             {
  404.                                                                 if (SearchNote == TieTarget)
  405.                                                                     {
  406.                                                                         if (!WriteBufferedSignedLongLittleEndian(
  407.                                                                             Output,FrameScan))
  408.                                                                             {
  409.                                                                                 return eFileLoadDiskError;
  410.                                                                             }
  411.                                                                         if (!WriteBufferedSignedLongLittleEndian(
  412.                                                                             Output,NoteScan))
  413.                                                                             {
  414.                                                                                 return eFileLoadDiskError;
  415.                                                                             }
  416.                                                                         if (!WriteBufferedSignedLongLittleEndian(
  417.                                                                             Output,SubFrameScan))
  418.                                                                             {
  419.                                                                                 return eFileLoadDiskError;
  420.                                                                             }
  421.                                                                         if (!WriteBufferedSignedLongLittleEndian(
  422.                                                                             Output,SubNoteScan))
  423.                                                                             {
  424.                                                                                 return eFileLoadDiskError;
  425.                                                                             }
  426.                                                                         goto DoneSearchingForTieTargetPoint;
  427.                                                                     }
  428.                                                             }
  429.                                                     }
  430.                                             }
  431.                                         EXECUTE(PRERR(ForceAbort,
  432.                                             "WriteNoteVector:  tie target couldn't be found"));
  433.                                         /* jump out here when tie target has been found */
  434.                                      DoneSearchingForTieTargetPoint:
  435.                                         ;
  436.                                     }
  437.                             }
  438.                     }
  439.             }
  440.         ERROR(NumberOfTieRecords != 0,PRERR(ForceAbort,
  441.             "WriteNoteVector:  tie record count inconsistency"));
  442.  
  443.         return eFileLoadNoError;
  444.     }
  445.